package com.tticar.invmanager.service.impl;

import com.baomidou.mybatisplus.entity.Columns;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tticar.invmanager.common.Enum.Status;
import com.tticar.invmanager.common.exception.MyServiceException;
import com.tticar.invmanager.common.shiro.LoginUser;
import com.tticar.invmanager.common.shiro.MySecurityUtils;
import com.tticar.invmanager.common.utils.MD5Utils;
import com.tticar.invmanager.entity.SysTenant;
import com.tticar.invmanager.entity.SysUser;
import com.tticar.invmanager.entity.vo.MyPage;
import com.tticar.invmanager.mapper.SysRoleResourceMapper;
import com.tticar.invmanager.mapper.SysTenantMapper;
import com.tticar.invmanager.mapper.SysUserMapper;
import com.tticar.invmanager.service.ISysDepartmentService;
import com.tticar.invmanager.service.ISysRoleService;
import com.tticar.invmanager.service.ISysUserService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 管理员账号 服务实现类
 * </p>
 *
 * @author joeyYan
 * @since 2018-06-27
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysTenantMapper tenantMapper;
    @Autowired
    private SysRoleResourceMapper roleResourceMapper;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysDepartmentService sysDepartmentService;

    @Override
    public Page selectPage(SysUser sysUser, MyPage<SysUser> page) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.ne(Status.STATUS.getDesc(), Status.DELETE.getCode());
        wrapper.like(Strings.isNotEmpty(sysUser.getUsername()), SysUser.USERNAME, sysUser.getUsername());
//        wrapper.like(Strings.isNotEmpty(sysUser.getNickname()), SysUser.NICKNAME, sysUser.getNickname());
        wrapper.eq(sysUser.getDeptId() != null, SysUser.DEPT_ID, sysUser.getDeptId());
        // 超级管理员不筛选用户列表
        wrapper.ne(MySecurityUtils.currentUser().getRoleId() == 1, SysUser.TENANT_ID, 0);
        return this.selectPage(page, wrapper);
    }

    @Override
    public List selectList(SysUser sysUser) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.ne(Status.STATUS.getDesc(), Status.DELETE.getCode());
        wrapper.like(Strings.isNotEmpty(sysUser.getUsername()), SysUser.USERNAME, sysUser.getUsername());
        wrapper.like(Strings.isNotEmpty(sysUser.getNickname()), SysUser.NICKNAME, sysUser.getNickname());
        wrapper.eq(sysUser.getDeptId() != null, SysUser.DEPT_ID, sysUser.getDeptId());
        wrapper.eq(sysUser.getTenantId() != null, SysUser.TENANT_ID, sysUser.getTenantId());
        return this.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> ids) {
        List list = new ArrayList();
        for (Long id : ids) {
            SysUser sysUser = new SysUser();
            sysUser.setId(id);
            //删除为-1，区分删除和禁用
            sysUser.setStatus(-1);
            list.add(sysUser);
        }
        this.updateBatchById(list);
    }

    @Override
    public LoginUser getLoginUser(String username) {
        Wrapper wrapper = Condition.create();
        wrapper.eq(SysUser.USERNAME, username).isNotNull(SysUser.TENANT_ID);

        Map map = this.selectMap(wrapper);
        LoginUser loginUser = new LoginUser();
        try {
            BeanUtils.populate(loginUser, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        SysTenant tenant = tenantMapper.selectById(loginUser.getTenantId());
        if (tenant == null || org.apache.commons.lang3.StringUtils.isBlank(tenant.getName())) {
            throw new UnknownAccountException("用户名不存在，或密码错误");
        }
        loginUser.setTenantName(tenant.getName());
        List pers = roleResourceMapper.selectPersByRoleId(loginUser.getRoleId());
        loginUser.setPers(pers);
        return loginUser;
    }

    @Override
//    @Async
    public void logLogin(LoginUser loginUser) {
        SysUser sysUser = this.selectById(loginUser.getId());
        if (sysUser.getLoginTime() == null) {
            sysUser.setLoginTime(new Date());
        }
        sysUser.setLastLoginTime(sysUser.getLoginTime());
        sysUser.setLoginTime(new Date());
        sysUser.setLoginTimes(sysUser.getLoginTimes() == null ? 1 : sysUser.getLoginTimes() + 1);
        this.updateById(sysUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysUser sysUser, String newPassword) {
        Wrapper w = Condition.create().eq(SysUser.USERNAME, sysUser.getUsername());
        w.ne(sysUser.getId() != null, SysUser.ID, sysUser.getId());
        Integer count = selectCount(w);
        if (count > 0) {
            throw MyServiceException.getInstance("用户名重复请重新填写");
        }
        if (sysUser.getId() == null) {
            sysUser.setPassword(MD5Utils.generatePasswordMD5(sysUser.getPassword(), null));
        }
        if (sysUser.getRoleId() != null && sysUser.getRoleId() != 2) {
            sysUser.setRoleName(sysRoleService.selectById(sysUser.getRoleId()).getName());
        }
        if (sysUser.getDeptId() != null) {
            sysUser.setDeptName(sysDepartmentService.selectById(sysUser.getDeptId()).getName());
        }
        if (StringUtils.hasText(newPassword)) {
            sysUser.setPassword(MD5Utils.generatePasswordMD5(newPassword, null));
        }
        if (StringUtils.isEmpty(sysUser.getMobile())) {
            sysUser.setMobile("");
        }
        if (StringUtils.isEmpty(sysUser.getNickname())) {
            sysUser.setNickname("");
        }
        this.insertOrUpdate(sysUser);
    }

}
